package com.cal.utms.model.csefileupload;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.json.JSONObject;

import com.cal.utms.entity.Csedownload;
import com.cal.utms.entity.Instrument;
import com.cal.utms.util.ValueConvert;

/**
 * Servlet implementation class UploadCsvFile
 */

public class UploadCsvFile extends HttpServlet {
	private static final long serialVersionUID = 1L;

	private static final String TMP_DIR_PATH = "/tempfiles";
	private File tmpDir;
	private static final String DESTINATION_DIR_PATH = "/files";
	private File destinationDir;
	private CseFileUploadModel cseFileUploadModel = new CseFileUploadModel();

	SimpleDateFormat format = new SimpleDateFormat("dd-MMM-yy", Locale.ENGLISH);
	SimpleDateFormat formatto = new SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH);

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public UploadCsvFile() {
		super();
		// TODO Auto-generated constructor stub
	}

	public void init(ServletConfig config) throws ServletException {

		super.init(config);
		String realPath = getServletContext().getRealPath(TMP_DIR_PATH);
		System.out.println(realPath);
		tmpDir = new File(realPath);
		if (!tmpDir.isDirectory()) {
			tmpDir.mkdir();
			// throw new ServletException(TMP_DIR_PATH + " is not a directory");
		}

		realPath = getServletContext().getRealPath(DESTINATION_DIR_PATH);
		destinationDir = new File(realPath);
		if (!destinationDir.isDirectory()) {
			destinationDir.mkdir();
			// throw new ServletException(DESTINATION_DIR_PATH +
			// " is not a directory");
		}

	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("GET");
		doPost(request, response);
		// response.sendError(HttpServletResponse.SC_BAD_REQUEST,
		// "HTTP GET method not supported");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("POST");

		// PrintWriter to send the JSON response back
		PrintWriter out = response.getWriter();
		// set content type
		response.setContentType("text/html");

		DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();

		// Set the size threshold, above which content will be stored on disk.
		fileItemFactory.setSizeThreshold(1 * 1024 * 1024); // 1 MB

		// Set the temporary directory to store the uploaded files of size above
		// threshold.
		fileItemFactory.setRepository(tmpDir);

		ServletFileUpload uploadHandler = new ServletFileUpload(fileItemFactory);

		String originalFileName = "";
		String extension = "";
		try {
			FileItem uploadedFile = null;
			// Parse the request
			List items = uploadHandler.parseRequest(request);
			Iterator iterator = items.iterator();
			while (iterator.hasNext()) {
				FileItem item = (FileItem) iterator.next();

				// Handle Form Fields

				if (item.getFieldName().equalsIgnoreCase("attachment") && !item.getName().isEmpty()) {
					uploadedFile = item;
				}
				System.out.println("Field Name = " + item.getFieldName() + ", File Name = " + item.getName() + ", Content type = " + item.getContentType() + ", File Size = "
						+ item.getSize());

				if (item.getSize() < 1 * 1024 * 1024) {
					originalFileName = item.getName();
					extension = originalFileName.substring(originalFileName.lastIndexOf('.') + 1);

					if (extension.equalsIgnoreCase("csv")) {

						if (item.isFormField()) {
							System.out.println("File Name = " + item.getFieldName() + ", Value = " + item.getString());
						}

						else {// Handle Uploaded files.
							System.out.println("Field Name = " + item.getFieldName() + ", File Name = " + item.getName() + ", Content type = " + item.getContentType()
									+ ", File Size = " + item.getSize());
							// Write file to the ultimate location.
							File file = new File(destinationDir, item.getName());
							item.write(file);

							BufferedReader br = null;
							String line = "";
							String cvsSplitBy = ",";

							List<String> csedownloads = cseFileUploadModel.getAllCSEdownload();
							List<Csedownload> updateCsedownloads = new ArrayList<Csedownload>();
							List<Instrument> instruments = new ArrayList<Instrument>();
							List<String> notmatchIssuer = new ArrayList<String>();
							try {

								br = new BufferedReader(new FileReader(destinationDir + "/" + item.getName()));
								while ((line = br.readLine()) != null) {
									// use comma as separator
									String[] cseline = line.split(cvsSplitBy);

									if (csedownloads.size() > 0) {
										System.out.println("hwqwhenk***");
										if (csedownloads.contains(cseline[0].trim())) {
											if (checkwithData(cseline)) {
												Csedownload csedownload = cseFileUploadModel.getBySymbol(cseline[0].trim());
												if (csedownload != null) {
													if (csedownload.getStatus().equals("Complite")) {
														csedownload.setUpdateDate(new Date());
													} else {
														csedownload.setUpdateDate(new Date());
														List<String> csecodelist = cseFileUploadModel.getMappedCSECode();
														if (csecodelist.contains(cseline[0].trim().split("/")[0])) {
															csedownload.setIssuerMapping("Mapped");
															Instrument instrument = cseFileUploadModel.createNONGOVTInstrument(cseline);
															if (instrument != null) {
																if (instrument.getInstrumentType() != null && instrument.getIssuer() != null) {
																	instruments.add(instrument);
																	csedownload.setStatus("Complite");
																} else {
																	csedownload.setStatus("Not Complite");
																}
															} else {
																csedownload.setStatus("Not Complite");
															}
														} else {
															if (!notmatchIssuer.contains(cseline[2].trim()))
																notmatchIssuer.add(cseline[2].trim());
															csedownload.setIssuerMapping("Not Mapped");
															csedownload.setStatus("Not Complite");
														}
													}
													updateCsedownloads.add(csedownload);
												}
											} else {
												System.out.println("not Match " + cseline[0]);
												JSONObject myObj = new JSONObject();
												myObj.put("mismatch", true);
												myObj.put("Result", "<font size=3 color=red>" + cseline[0].trim() + " is not matching with previous record </font>");
												out.println(myObj.toString());
												out.close();
												return;
											}
										} else {
											Csedownload csedownload = new Csedownload();
											if (cseline[0].trim().split("/")[0].equals("GOVT")) {
												csedownload.setIssuerMapping("Mapped");
												Instrument instrument = cseFileUploadModel.createGOVTInstrument(cseline);
												if (instrument != null) {
													if (instrument.getInstrumentType() != null && instrument.getIssuer() != null) {
														csedownload.setStatus("Complite");
														instruments.add(instrument);
													} else {
														csedownload.setStatus("Not Complite");
													}
												} else {
													csedownload.setStatus("Not Complite");
												}
											} else {
												List<String> csecodelist = cseFileUploadModel.getMappedCSECode();
												if (csecodelist.contains(cseline[0].trim().split("/")[0])) {
													csedownload.setIssuerMapping("Mapped");
													Instrument instrument = cseFileUploadModel.createNONGOVTInstrument(cseline);
													if (instrument != null) {
														if (instrument.getInstrumentType() != null && instrument.getIssuer() != null) {
															instruments.add(instrument);
															csedownload.setStatus("Complite");
														} else {
															csedownload.setStatus("Not Complite");
														}
													} else {
														csedownload.setStatus("Not Complite");
													}
												} else {
													if (!notmatchIssuer.contains(cseline[2].trim()))
														notmatchIssuer.add(cseline[2].trim());
													csedownload.setIssuerMapping("Not Mapped");
													csedownload.setStatus("Not Complite");
												}
											}
											csedownload.setSymbol(cseline[0].trim());
											csedownload.setIsin(cseline[1].trim());
											csedownload.setIssuerName(cseline[2].trim());
											csedownload.setCurrency(cseline[3].trim());
											csedownload.setIssuerPrice(cseline[4].trim());
											csedownload.setCouponType(cseline[5].trim());
											if (cseline[6].trim().length() > 0)
												csedownload.setCouponRate(ValueConvert.toBigDecimal(cseline[6].trim()));
											else
												csedownload.setCouponRate(BigDecimal.ZERO);
											csedownload.setPaymentPeriod(cseline[7].trim());
											csedownload.setMaturity(cseline[8].trim());
											csedownload.setDayCount(cseline[9].trim());
											csedownload.setRedemptionTerm(cseline[10].trim());
											csedownload.setParValue(ValueConvert.toInteger(cseline[11].trim()));
											csedownload.setDateIssued(cseline[12].trim());
											csedownload.setIssuedQuantity(ValueConvert.toBigDecimal(cseline[13].trim()));
											csedownload.setUpdateDate(new Date());

											updateCsedownloads.add(csedownload);
										}
									} else { // First Time Upload
										System.out.println("hettt");
										Csedownload csedownload = new Csedownload();
										if (cseline[0].trim().split("/")[0].equals("GOVT")) {
											csedownload.setIssuerMapping("Mapped");
											Instrument instrument = cseFileUploadModel.createGOVTInstrument(cseline);
											if (instrument != null) {
												if (instrument.getInstrumentType() != null && instrument.getIssuer() != null) {
													csedownload.setStatus("Complite");
													instruments.add(instrument);
												} else {
													csedownload.setStatus("Not Complite");
												}
											} else {
												csedownload.setStatus("Not Complite");
											}
										} else {
											List<String> csecodelist = cseFileUploadModel.getMappedCSECode();
											if (csecodelist.contains(cseline[0].trim().split("/")[0])) {
												csedownload.setIssuerMapping("Mapped");
												Instrument instrument = cseFileUploadModel.createNONGOVTInstrument(cseline);
												if (instrument != null) {
													if (instrument.getInstrumentType() != null && instrument.getIssuer() != null) {
														instruments.add(instrument);
														csedownload.setStatus("Complite");
													} else {
														csedownload.setStatus("Not Complite");
													}
												} else {
													csedownload.setStatus("Not Complite");
												}
											} else {
												if (!notmatchIssuer.contains(cseline[2].trim()))
													notmatchIssuer.add(cseline[2].trim());
												csedownload.setIssuerMapping("Not Mapped");
												csedownload.setStatus("Not Complite");
											}
										}
										csedownload.setSymbol(cseline[0].trim());
										csedownload.setIsin(cseline[1].trim());
										csedownload.setIssuerName(cseline[2].trim());
										csedownload.setCurrency(cseline[3].trim());
										csedownload.setIssuerPrice(cseline[4].trim());
										csedownload.setCouponType(cseline[5].trim());
										if (cseline[6].trim().length() > 0)
											csedownload.setCouponRate(ValueConvert.toBigDecimal(cseline[6].trim()));
										else
											csedownload.setCouponRate(BigDecimal.ZERO);
										csedownload.setPaymentPeriod(cseline[7].trim());
										csedownload.setMaturity(cseline[8].trim());
										csedownload.setDayCount(cseline[9].trim());
										csedownload.setRedemptionTerm(cseline[10].trim());
										csedownload.setParValue(ValueConvert.toInteger(cseline[11].trim()));
										csedownload.setDateIssued(cseline[12].trim());
										csedownload.setIssuedQuantity(ValueConvert.toBigDecimal(cseline[13].trim()));
										csedownload.setUpdateDate(new Date());

										updateCsedownloads.add(csedownload);
									}
								}
								cseFileUploadModel.saveUpdateCseDownloads(updateCsedownloads, instruments);

							} catch (FileNotFoundException e) {
								e.printStackTrace();
								JSONObject myObj = new JSONObject();
								myObj.put("invalidformat", false);
								out.println(myObj.toString());
								out.close();
							} catch (IOException e) {
								e.printStackTrace();
								JSONObject myObj = new JSONObject();
								myObj.put("invalidformat", false);
								out.println(myObj.toString());
								out.close();
							} finally {
								if (br != null) {
									try {
										br.close();
									} catch (IOException e) {
										e.printStackTrace();
									}
								}
							}
							// Create a JSON object to send response
							JSONObject myObj = new JSONObject();
							// sets success to true
							myObj.put("success", true);
							if (notmatchIssuer.size() > 0) {
								String msg = "Following Issuers not found </font>";
								for (String string : notmatchIssuer) {
									msg = msg + "</br>" + string;
								}
								myObj.put("NotMatchISSUER", msg);
							}
							out.println(myObj.toString());
							out.close();
						}
					} else {
						System.out.println("invalid extention");
						JSONObject myObj = new JSONObject();
						myObj.put("invalidformat", false);
						out.println(myObj.toString());
						out.close();
					}
				} else {
					System.out.println("File too large");
				}

			}
		} catch (FileUploadException ex) {
			log("Error encountered while parsing the request", ex);
		} catch (Exception ex) {
			log("Error encountered while uploading file", ex);
		}
	}

	private boolean checkwithData(String[] cseline) {
		boolean flag = false;
		if (cseline != null) {
			Csedownload symbol = cseFileUploadModel.getSymbolByData(cseline[1].trim(), cseline[2].trim(), cseline[3].trim(), cseline[4].trim(), cseline[5].trim(),
					cseline[6].trim(), cseline[7].trim(), cseline[8].trim(), cseline[9].trim(), cseline[10].trim(), cseline[11].trim(), cseline[12].trim(), cseline[13].trim());
			if (symbol != null) {
				if (symbol.getSymbol().trim().equals(cseline[0].trim())) {
					flag = true;
				} else {
					flag = false;
				}
			} else {
				flag = false;
			}
		} else {
			flag = false;
		}
		return flag;
	}

}
